package org.wpahs.ahn.rssfeed;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Base64;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.webkit.URLUtil;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import org.wpahs.ahn.rssfeed.DB.DBFeedItem;
import org.wpahs.ahn.rssfeed.DB.DBMyFeed;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;




/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link FeedsFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link FeedsFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class FeedsFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    //private FeedTask mTask = null;
    private BounceListView mFeedList = null;
    private FeedAdapter mAdapter = null;

    private SwipeRefreshLayout mSwipeLayout = null;
    //private Button mBtnMarkAllAsRead = null;
    private TextView mFeedEmtpy = null;

    private int mFeedId = 0;
    private MyFeed mFeed = null;
    private int scrollTo;
    //private Map<Integer, Bitmap> bitMaps = new HashMap<Integer, Bitmap>();
    private List<Integer> mFeedIds = new ArrayList<>();

    private boolean hadNoContext = false;
    private SparseArray<String> mFeedTitles = new SparseArray<>();
    private SparseArray<FeedItem>mFeeds = new SparseArray<>();
    private SparseArray<Bitmap>mBitmaps = new SparseArray<>();

    final float mDefaultVelocity = 150;


    int lastScrollLocation = 0;
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    private int orientation = Surface.ROTATION_0;

    private SimpleDateFormat sdf = new SimpleDateFormat("MM.dd.yyyy HH:mm");
    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment FeedFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static FeedsFragment newInstance() {
        FeedsFragment fragment = new FeedsFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public FeedsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onStart(){
        //loadFeed(this.getActivity());

        if(hadNoContext){
            loadFeed(this.getActivity());
            hadNoContext = false; //reset
        }

        super.onStart();
    }

    @Override
    public void onConfigurationChanged(Configuration config){
        super.onConfigurationChanged(config);
        try {
            Display display = ((WindowManager) getActivity().getSystemService(Activity.WINDOW_SERVICE))
                    .getDefaultDisplay();

            orientation = display.getRotation();
        }catch (Exception ex){
            Log.e("onConfigurationChanged",
                    (ex.getMessage() !=null ? ex.getMessage() : "no ex msg"));

        }
    }

    public void setFeedId(int feedId){
        boolean loadFeed=true;
        if(mFeedId != feedId) {
            mFeedId = feedId;
        }else{
            loadFeed = false;
        }

        if(this.getActivity()!=null){
            hadNoContext=false;
            if(loadFeed) {
                loadFeed(this.getActivity());
            }
        }else{
            hadNoContext = true;
        }
    }

    public int getFeedId(){
        return mFeedId;
    }

    public void setBitmap(final int feedItemId){
        try {
            if(mAdapter == null) return;
            DBFeedItem db = new DBFeedItem(getActivity());
            String b64 = db.getImage(feedItemId);
            db.close();
            Log.i("setBitmap","Attempting from DB- " + String.valueOf(feedItemId) + " - " + String.valueOf(b64.length()));
            Bitmap fromDbBitmap = decodeBase64(b64);
            if(fromDbBitmap == null){
                Log.i("setBitmap","Bitmap was null");
            }else{
                mBitmaps.put(feedItemId,fromDbBitmap);
                //mBitmaps.put(feedItemId,fromDbBitmap);
                Log.i("setBitmap","Add to mBitmaps size of " + String.valueOf(fromDbBitmap.getByteCount()));
                int position = mAdapter.getPosition(feedItemId);
                View v = mFeedList.getChildAt(position);

                if(v != null){
                    FeedItemHolder fih = (FeedItemHolder)v.getTag();
                    if(fih != null){
                        fih.ivImage.setImageBitmap(fromDbBitmap);
                        Log.i("setBitmap","Updating visible position " + String.valueOf(position));
                    }else{
                        Log.i("setBitmap","FileItemHolder is null " + String.valueOf(position));
                    }
                }else{
                    Log.i("setBitmap","Skipping non visible position " + String.valueOf(position));

                }


            }

            /*
            final int position = mAdapter.getPosition(feedItemId);
            if (position >= 0) {
                View v = mFeedList.getChildAt(position);
                if (v != null) {
                    final FeedItemHolder holder = (FeedItemHolder) v.getTag();
                    holder.ivImage.postDelayed(
                            new Runnable() {
                                @Override
                                public void run() {
                                    DBFeedItem db = new DBFeedItem(getActivity());
                                    String b64 = db.getImage(feedItemId);
                                    Log.i("getView","Attempting from DB- " + String.valueOf(feedItemId) + " - " + String.valueOf(b64.length()));
                                    Bitmap fromDbBitmap = decodeBase64(b64);
                                    if(fromDbBitmap == null){
                                        Log.i("getView","Bitmap was null");
                                    }
                                    db.close();
                                    mBitmaps.put(feedItemId,fromDbBitmap);
                                    //((View)holder.ivImage.getParent()).setVisibility(View.VISIBLE);
                                    holder.ivImage.setImageBitmap(fromDbBitmap);
                                    holder.tvTitle.setText(holder.tvTitle.getText() + " Updated");
                                }
                            },100
                    );
                }
            }
            */


        }catch (Exception ex){
            Log.e("setBitmap", (ex.getMessage() == null ? "ex message is null " : ex.getMessage()));

        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState != null) {
            scrollTo = savedInstanceState.getInt("firstVisiblePosition", 0);

        }
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_feed, container, false);
        try {
            Display display = ((WindowManager) getActivity().getSystemService(Activity.WINDOW_SERVICE))
                    .getDefaultDisplay();

            orientation = display.getRotation();
        }catch (Exception ex){
            Log.e("onConfigurationChanged",
                    (ex.getMessage() !=null ? ex.getMessage() : "no ex msg"));

        }
        setupUI(v);
        return v;
    }

    private void setupUI(View v){
        mSwipeLayout = (SwipeRefreshLayout)v.findViewById(R.id.FeedSwipeLayout);
        mFeedList = (BounceListView) v.findViewById(R.id.FeedList);
        mFeedList.setSaveEnabled(true);
        mFeedList.setScrollingCacheEnabled(false);
        mFeedList.setAnimationCacheEnabled(false);


        mFeedList.setOnBounceUpListener(new BounceListView.OnBounceEventListener() {

            @Override
            public void onFlungY() {
                markAllAsRead(getActivity());
            }
        });

        /*
        mFeedEmtpy = (TextView)v.findViewById(R.id.FeedEmpty);

        if(mFeedEmtpy != null) {
            mFeedList.setEmptyView(mFeedEmtpy);

        }
        */
        /*
        mBtnMarkAllAsRead = (Button)v.findViewById(R.id.FeedMarkAllRead);
        mBtnMarkAllAsRead.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                markAllAsRead(v.getContext());
            }
        });
        */
        mFeedList.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                int padding=10;
                for(int x = 0; x < totalItemCount; x++){
                    if(mAdapter.isEmpty()) return;
                    final int itemId = mAdapter.getItem(x);
                    if(x > 0 &&
                            (x >=(firstVisibleItem-padding) &&
                                x <=(firstVisibleItem + visibleItemCount + padding))&&
                            (x < firstVisibleItem || x > (firstVisibleItem+visibleItemCount))
                            ){
                        Bitmap bm = mBitmaps.get(itemId,null);
                        if(bm == null){
                            new Runnable() {
                                @Override
                                public void run() {
                                    Bitmap bitmap;
                                    DBFeedItem db = new DBFeedItem(getActivity());
                                    String b64 = db.getImage(itemId);
                                    db.close();
                                    bitmap = FeedsFragment.decodeBase64(b64);

                                    if(bitmap != null){
                                        mBitmaps.put(itemId,bitmap);
                                    }
                                }
                            }.run();
                        }
                    }else{
                        if(x >= 0) {
                            mBitmaps.remove(itemId);
                        }
                    }
                }

            }
        });
        mFeedList.scrollTo(0,scrollTo);


        mSwipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mSwipeLayout.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            if(mFeedId >=0) {
                                ((MainActivity) getActivity()).onFragmentRequestRefresh(mFeedId, true);
                            }
                        } catch (ClassCastException e) {
                            throw new ClassCastException(getActivity().toString()
                                    + " must implement OnFragmentInteractionListener");
                        }
                    }
                });
            }
        });



    }


    @Override
    public void onSaveInstanceState(Bundle b){
        b.putInt("firstVisiblePosition",mFeedList.getFirstVisiblePosition());
        super.onSaveInstanceState(b);
    }

    public void scrollTo(int position){
        mFeedList.smoothScrollToPosition(position);
    }
    @Override
    public void onViewStateRestored(Bundle b){
        super.onViewStateRestored(b);
        /*
        if(b != null) {
            if (b.containsKey("firstVisiblePosition")) {
                int lastScrollPosition = b.getInt("firstVisiblePosition", 0);
                if (mFeedList != null) {
                    mFeedList.smoothScrollToPosition(lastScrollPosition);
                }
            }
        }
        */
    }




    public void markAllAsRead(final Context c){

        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which){
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        try {
                            try {
                                View v;
                                //go backwards so we don't throw off the positions
                                for (int position = mAdapter.getCount()-1; position>=0; position--) {
                                    v = mAdapter.getView(position, null, null);
                                    Log.i("marking read", String.valueOf(position));
                                    if (v != null) {
                                        FeedItemHolder holder = (FeedItemHolder) v.getTag();
                                        if (holder != null) {
                                            doneIt(holder.llSlider);
                                        }
                                    }
                                }
                                mAdapter.notifyDataSetChanged();
                                mFeedList.invalidateViews();
                            }catch (Exception ex){
                                Log.e("markAllAsRead", ex.getMessage());
                            }
                            loadFeed(c);


                        }catch (Exception ex){
                            Toast.makeText(mContext,ex.getMessage(),Toast.LENGTH_SHORT).show();
                        }
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setMessage("Mark these items read?").setPositiveButton(getString(R.string.yes), dialogClickListener)
                .setNegativeButton(getString(R.string.no), dialogClickListener).show();


       /*
        DBFeedItem db = new DBFeedItem(c);
        for(Integer itemId : mFeedIds){
            db.setRead(itemId,true);
        }
        db.close();
        loadFeed(c);
        */
    }

    @Override
    public void onResume(){

        super.onResume();
    }


    Runnable mRefreshing = new Runnable() {
        public void run() {
            mSwipeLayout.setRefreshing(true);
        }
    };

    Runnable mLoadingFeed = new Runnable() {
        @Override
        public void run() {
            //mFeedList.setEnabled(false);
            List<FeedItem> tempFeeds;
            mFeeds.clear();
            mFeedIds.clear();
            mBitmaps.clear();
            DBFeedItem fi = new DBFeedItem(mContext);
            if(mFeedId == 0) {
                tempFeeds = fi.getAllItems(false);
            }else if(mFeedId==-2){
                //we're getting favorites
                tempFeeds = fi.getAllFavorites();
            }else{ // we are just getting a specific feed
                tempFeeds = fi.getItemsByFeed(mFeedId,false);
            }
            fi.close();

            for(FeedItem item : tempFeeds){
                mFeeds.put(item.getItemId(),item);
                mFeedIds.add(item.getItemId());
            }

            if(mFeed == null){
                if(mFeedId > 0) {
                    DBMyFeed db = new DBMyFeed(mContext);
                    mFeed = db.getFeed(mFeedId);
                    db.close();
                }else if(mFeedId == -2){ ///it's favorites
                    mFeed = new MyFeed();
                    mFeed.setId(-2);
                    mFeed.setTitle("Favorites");
                }else{
                    mFeed = new MyFeed();
                    mFeed.setId(0);
                    mFeed.setTitle("All");
                }
            }else{
                DBMyFeed db = new DBMyFeed(mContext);
                mFeed = db.getFeed(mFeedId);
                db.close();
            }

            if(mAdapter == null){
                mAdapter = new FeedAdapter(mContext, R.layout.slide_item_layout, mFeedIds);
            }
            mFeedList.setAdapter(mAdapter);

            mAdapter.notifyDataSetChanged();

            if(mFeedIds.size() == 0) {
                if(mFeedEmtpy == null){
                    mFeedEmtpy = new TextView(getActivity());
                    mFeedEmtpy.setTextSize(24f);
                }
                if (mFeedEmtpy != null) {
                    String textToShow;
                    if (mFeed == null) {
                        //mFeedEmtpy.setText("No more news");
                        textToShow = "No more news";
                    } else {
                        //mFeedEmtpy.setText("No more news from " + mFeed.getTitle());
                        textToShow = "No more news from " + mFeed.getTitle();
                    }
                    mFeedEmtpy.setText(textToShow);
                    if(mFeedList.getHeaderViewsCount() == 0){
                        mFeedList.addHeaderView(mFeedEmtpy);
                    }
                }
            }else{
                if(mFeedEmtpy != null)
                if (mFeedList.getHeaderViewsCount() > 0) {
                    mFeedList.removeHeaderView(mFeedEmtpy);
                }
            }
            mFeedList.invalidateViews();

            mSwipeLayout.removeCallbacks(mRefreshing);
            mSwipeLayout.setRefreshing(false);
            //mFeedList.setEnabled(true);
            //((MainActivity)getActivity()).mrLayout.setRefreshing(false);
        }
    };
    private Context mContext = null;
    public void loadFeed(Context context){
        if(this.getActivity() == null) {
            hadNoContext = true;
            return;
        }
        mContext = context;
        mSwipeLayout.post(mRefreshing);
        mSwipeLayout.postDelayed(mLoadingFeed,500);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            ((MainActivity) activity).onSectionAttached(mFeedId);
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }


    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
       // public void onFragmentInteraction(Uri uri);
    }



    public class FeedAdapter extends ArrayAdapter<Integer> {
        Context mContext;

        public FeedAdapter(Context context, int resource, List<Integer> objects) {
            super(context, resource, objects);
            setRetainInstance(true);
            mContext = context;

        }

        @Override
        public View getView(int position, View feedView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            final FeedItemHolder holder;
            final int feedItemId = this.getItem(position);
            FeedItem fi = mFeeds.get(feedItemId);
            final int feedId = fi.getFeedId();

            if(feedView == null){
                feedView= inflater.inflate(R.layout.slide_item_layout, parent, false);
                holder = new FeedItemHolder();
                holder.ivImage =(ImageView) feedView.findViewById(R.id.ItemImage);
                holder.llImageHolder=(LinearLayout)feedView.findViewById(R.id.ItemImageHolder);
                holder.tvTitle = (TextView) feedView.findViewById(R.id.ItemTitle);

                holder.tvPublishedDate = (TextView) feedView.findViewById(R.id.ItemPubDate);

                holder.tvFeedTitle = (TextView)feedView.findViewById(R.id.ItemFeedTitle);

                holder.llSlider= (LinearLayout)feedView.findViewById(R.id.ItemSlider);
                //holder.llSlider.setOnTouchListener(new SwipeDetector(holder.llSlider, position));
                holder.ivFavorite =(ImageView)feedView.findViewById(R.id.ItemFavorite);
                holder.position = position;
            }else{
                holder = (FeedItemHolder)feedView.getTag();
            }
            holder.position = position;
            holder.feedId = fi.getFeedId();
            holder.feedItemId = fi.getItemId();
            holder.loadedImage =false;
            feedView.setTag(holder);

            if(holder.llImageHolder !=null){
                if(orientation == Surface.ROTATION_0 || orientation == Surface.ROTATION_180){
                    //holder.llImageHolder.setWeightSum(5f);
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            5F
                    );
                    holder.llImageHolder.setLayoutParams(lp);
                }else{
                    //it's landscape
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            10f
                    );
                    holder.llImageHolder.setLayoutParams(lp);
                }
            }

            feedView.setOnTouchListener(null);
            feedView.setOnTouchListener(new SwipeDetector(holder.llSlider));

            holder.llSlider.setTag(position);

            feedView.setEnabled(true);

            RelativeLayout.LayoutParams params =
                    (RelativeLayout.LayoutParams) holder.llSlider.getLayoutParams();
            params.rightMargin = 0;
            params.leftMargin = 0;
            holder.llSlider.setLayoutParams(params);

            feedView.setId(fi.getItemId());

            //holder.ivImage.setImageBitmap(((MainActivity) getActivity()).getFeedBitmap(feedId));
                holder.ivImage.post(new Runnable() {
                    @Override
                    public void run() {
                        Bitmap bm = mBitmaps.get(feedItemId, null);
                        if (bm != null) {
                            holder.ivImage.setImageBitmap(bm);

                        } else {
                            DBFeedItem db = new DBFeedItem(getActivity());
                            String b64 = db.getImage(feedItemId);
                            db.close();
                            bm = decodeBase64(b64);

                            if (bm == null) {
                                bm = ((MainActivity) getActivity()).getFeedBitmap(feedId);
                            }else{
                                mBitmaps.put(feedItemId, bm);
                            }
                            if (currentapiVersion >= Build.VERSION_CODES.LOLLIPOP) {
                                //holder.ivImage.setElevation(25f);
                            }
                            holder.ivImage.setImageBitmap(bm);
                        }
                        holder.loadedImage =true;
                        fadeIn(holder.ivImage);

                    }

                });


            holder.tvTitle.setText(fi.getTitle());

            String feedTitle = mFeedTitles.get(fi.getFeedId());
            if(feedTitle == null){
                DBMyFeed dbMyFeed = new DBMyFeed(getContext());
                MyFeed mf = dbMyFeed.getFeed(fi.getFeedId());
                dbMyFeed.close();
                feedTitle = ((mf.getTitle() == null)? mf.getUrl() : mf.getTitle());
                mFeedTitles.put(fi.getFeedId(), feedTitle);
            }
            holder.tvFeedTitle.setText(feedTitle);

            if(holder.ivFavorite != null ){
                if(fi.getIsFavorite()){
                    holder.ivFavorite.setImageResource(R.drawable.ic_action_good);
                }else{
                    holder.ivFavorite.setImageResource(R.drawable.ic_action_bad);
                }
                holder.ivFavorite.setTag(fi.getItemId());
                holder.ivFavorite.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Vibrator girl = (Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE);
                        if(girl != null && girl.hasVibrator()){
                            girl.vibrate(50);
                        }
                        DBFeedItem db = new DBFeedItem(v.getContext());
                        FeedItem fi = mFeeds.get((int)v.getTag());
                        fi.setIsFavorite(!fi.getIsFavorite());
                        mFeeds.put(fi.getItemId(),fi);
                        db.setFavorite((int)v.getTag(),fi.getIsFavorite());
                        ImageView iv = (ImageView)v;
                        if(fi.getIsFavorite()){
                            iv.setImageResource(R.drawable.ic_action_good);
                        }else{
                            iv.setImageResource(R.drawable.ic_action_bad);
                        }
                    }
                });
            }

            try {
                holder.tvPublishedDate.setText(sdf.format(fi.getPubDateAsDate()));
            } catch (Exception ex) {
                holder.tvPublishedDate.setText(fi.getPubDate());

            }
            feedView.setTag(holder);

            return feedView;
        }

    }

    private void fadeIn(View v){
        FadeInAnimation fadeIn = new FadeInAnimation(0f,100f);
        v.startAnimation(fadeIn);
    }



    public void onClick(View v) {
        int position = (int)v.getTag();
        int feedItemId = mAdapter.getItem(position);
        String url = mFeeds.get(feedItemId).getLink();
        if(URLUtil.isValidUrl(url)) {
            Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url));
            v.getContext().startActivity(intent);
        }else{
            if(url == null){url = "NULL";}
            Toast.makeText(v.getContext(),"bad url: " + url,Toast.LENGTH_SHORT).show();
        }
    }



    public boolean longClick(View v) {
        Vibrator girl = (Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE);
        if(girl != null && girl.hasVibrator()){
            girl.vibrate(50);
        }
        final View dv = v;
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which){
                    case DialogInterface.BUTTON_POSITIVE:
                        //Yes button clicked
                        try {
                            int position = (int) dv.getTag();
                            //DBFeedItem fi = new DBFeedItem(dv.getContext());
                            View temp;
                            //DBFeedItem db = new DBFeedItem(dv.getContext());
                            for (int i = position; i>=0; i--) {
                                //int feedItemId = mAdapter.getItem(i);
                                temp = mAdapter.getView(i,null,null);
                                FeedItemHolder fih = (FeedItemHolder)temp.getTag();
                                doneIt(fih.llSlider);
                                //db.setRead(feedItemId, true);
                                //mFeedIds.remove(i);
                            }
                            //db.close();
                            mAdapter.notifyDataSetChanged();
                            //mFeedList.invalidateViews();

                        }catch (Exception ex){
                            Toast.makeText(dv.getContext(),ex.getMessage(),Toast.LENGTH_SHORT).show();
                            Log.d("OnLongClick", ex.getMessage());
                        }
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        //No button clicked
                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());

        builder.setMessage("Mark this and previous items read?").setPositiveButton("Yes!", dialogClickListener)
                .setNegativeButton(getString(R.string.no), dialogClickListener).show();

        return true;
    }


    private void shareIt(View v){
        try {
            Vibrator girl = (Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE);
            if(girl != null && girl.hasVibrator()){
                girl.vibrate(50);
            }
            v.setEnabled(false);
            int position = (int)v.getTag();
            int feedItemId= mAdapter.getItem(position);
            FeedItem fi = mFeeds.get(feedItemId);
            Intent sharing = new Intent(Intent.ACTION_SEND);
            sharing.setType("text/plain");
            sharing.putExtra(Intent.EXTRA_TEXT, fi.getLink());
            sharing.putExtra(android.content.Intent.EXTRA_SUBJECT, "Hmmm! : " + fi.getTitle());
            startActivity(Intent.createChooser(sharing, "Share"));
            v.setEnabled(true);
            /*
            Toast.makeText(v.getContext(),
                    String.valueOf(position) + " -- " +
                    String.valueOf(feedItemId),
                    Toast.LENGTH_SHORT).show();
                    */

        }catch (Exception e){
            Log.e("shareit", e.getMessage());
        }
    }

    private static Bitmap decodeBase64(String input) {
        Bitmap retval = null;
        try {
            if (input != null) {
                byte[] decodedByte = Base64.decode(input, 0);
                retval = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
            }
        }catch (Exception ex) {
            ex.printStackTrace();
        }
        System.gc();
        return retval;
    }

    static class FeedItemHolder {
        ImageView ivImage;
        TextView tvTitle;
        TextView tvPublishedDate;
        TextView tvFeedTitle;
        LinearLayout llSlider;
        LinearLayout llImageHolder;
        ImageView ivFavorite;
        int position;
        int feedId;
        int feedItemId;
        boolean loadedImage = false;
    }

    private void doneIt(View v){
        DBFeedItem db = new DBFeedItem(v.getContext());
        int position = (int) v.getTag();
        Integer feedItemId = mAdapter.getItem(position);
        db.setRead(feedItemId, true);
        db.close();
        mFeedIds.remove(feedItemId);
        mFeeds.remove(feedItemId);
        mBitmaps.remove(feedItemId);
    }

    private void doneIt(View v,float velocity) {
        try {
            //v.setEnabled(false);
            mFeedList.setVerticalScrollbarPosition(lastScrollLocation);
            final View animView = v;
            final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)animView.getLayoutParams();
            final ValueAnimator anim = ValueAnimator.ofInt(lp.leftMargin,animView.getWidth());
            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){

                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    lp.leftMargin = (Integer)animation.getAnimatedValue();
                    lp.rightMargin = -(Integer)animation.getAnimatedValue();
                    animView.requestLayout();
                }
            });
            anim.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    try {
                        DBFeedItem db = new DBFeedItem(animView.getContext());
                        int position = (int) animView.getTag();
                        Integer feedItemId = mAdapter.getItem(position);
                        db.setRead(feedItemId, true);
                        db.close();
                        mFeedIds.remove(feedItemId);
                        mFeeds.remove(feedItemId);
                        mBitmaps.remove(feedItemId);
                        mAdapter.notifyDataSetChanged();
                        //mFeedList.invalidateViews();

                    }catch (Exception ex){
                        Toast.makeText(
                                animView.getContext(),
                                ex.getMessage(),
                                Toast.LENGTH_SHORT)
                                .show();
                    }
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            velocity = velocity * .10f;
            anim.setDuration(Math.round(mDefaultVelocity));
            Log.i("Fling Animation",String.valueOf(velocity));
            anim.start();


        } catch (Exception e) {
            Log.e("doneIt", e.getMessage());
        }
    }

    public class SwipeDetector implements View.OnTouchListener {

        private View mView = null;
        private int MIN_DISTANCE;
        private final int MIN_LOCK_DISTANCE = 20; // disallow motion intercept
        private boolean motionInterceptDisallowed = false;
        private float downX, upX;
        private RelativeLayout mLayout = null;
        private ImageView mIvDone = null;
        private ImageView mIvShare = null;
        private long downTime;
        private Boolean isLongPressed = false;
        private boolean isClicked = false;
        private boolean flinging = false;

        final Handler mLongHandler = new Handler();
        VelocityTracker mVelocityTracker =null;
        ViewConfiguration mViewConfiguration = null;
        Runnable mLongPressed = new Runnable() {
            public void run() {
                if(!motionInterceptDisallowed){
                    //do long press
                    isLongPressed=true;
                    longClick(mView);
                }
            }
        };



        public SwipeDetector(View v){
            mView = v;
            mViewConfiguration = ViewConfiguration.get(v.getContext());
            mVelocityTracker = VelocityTracker.obtain();
            mLayout = (RelativeLayout)mView.getParent();
            mIvDone = (ImageView)mLayout.findViewById(R.id.ItemSlideDone);
            mIvShare = (ImageView)mLayout.findViewById(R.id.ItemSlideShare);
        }


        @Override
        public boolean onTouch(View v, MotionEvent event) {
            MIN_DISTANCE = (MIN_DISTANCE == 0 ? Math.round(v.getWidth() *1f) : MIN_DISTANCE);
            mVelocityTracker.addMovement(event);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    downX = event.getX();
                    downTime = event.getEventTime();
                    isClicked=false;
                    isLongPressed=false;
                    flinging = false;
                    //start a timer
                    mLongHandler.postDelayed(mLongPressed,1500);
                    return true; // allow other events like Click to be processed
                }

                case MotionEvent.ACTION_MOVE: {
                    if(isLongPressed) {return true;}
                    upX = event.getX();
                    float deltaX = downX - upX;
                    if (Math.abs(deltaX) > MIN_LOCK_DISTANCE && mFeedList != null && !motionInterceptDisallowed) {
                        mLongHandler.removeCallbacks(mLongPressed);
                        mFeedList.requestDisallowInterceptTouchEvent(true);
                        motionInterceptDisallowed = true;
                    }

                    if(!isLongPressed && motionInterceptDisallowed) {
                        deltaX = -deltaX;
                        swipe(deltaX);

                        if (deltaX > 0) { //do your color and icon work
                            //moving right

                            mLayout.setBackgroundColor(Color.parseColor("#00a651"));
                            mIvShare.setVisibility(View.GONE);
                            mIvDone.setVisibility(View.VISIBLE);
                        } else {
                            // moving left
                            mLayout.setBackgroundColor(Color.BLUE);
                            mIvShare.setVisibility(View.VISIBLE);
                            mIvDone.setVisibility(View.GONE);
                        }
                    }
                    return true;
                }
                case MotionEvent.ACTION_UP:
                    mLongHandler.removeCallbacks(mLongPressed);
                    long duration = event.getEventTime() - downTime;
                    Log.i("getDownTime", String.valueOf(duration));
                    isClicked = false;

                    if( duration <= 300 && !motionInterceptDisallowed){
                        isClicked=true;
                        onClick(mView);
                    }

                    mVelocityTracker.computeCurrentVelocity(1000,mViewConfiguration.getScaledMaximumFlingVelocity());
                    float xVelocity = mVelocityTracker.getXVelocity();
                    Log.i("xVelocity",String.valueOf(xVelocity) + " -- " + mViewConfiguration.getScaledMaximumFlingVelocity() +
                    " -- " + mViewConfiguration.getScaledMinimumFlingVelocity());
                    if (Math.abs(mVelocityTracker.getXVelocity()) > 2900f) { //mViewConfiguration.getScaledMaximumFlingVelocity()) {
                        // horizontal fling!
                        flinging=true;
                    }

                    if(!isClicked && !isLongPressed ) {
                        upX = event.getX();
                        float deltaX = upX - downX;

                        if(!flinging) {
                            swipe(0);

                        }else{
                            swipeDo(deltaX,mVelocityTracker.getXVelocity());
                        }
                    }else{
                        swipe(0);
                        v.setEnabled(true); //re-enable after long press
                    }

                    if (mFeedList != null) {
                        mFeedList.requestDisallowInterceptTouchEvent(false);
                        motionInterceptDisallowed = false;
                    }
                    mVelocityTracker.clear();
                    return true;

                case MotionEvent.ACTION_CANCEL:
                    //v.setVisibility(View.VISIBLE);
                    // mLayout.setBackgroundColor(Color.TRANSPARENT);
                    mLongHandler.removeCallbacks(mLongPressed);
                    v.setEnabled(true);
                    isLongPressed=false;
                    isClicked=false;
                    mVelocityTracker.clear();
                    swipe(0);
                    return false;
            }

            return true;
        }

        private void swipe(final float distance) {
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams();
            int d = Math.round(distance);
            params.rightMargin = -d;
            params.leftMargin = d;
            mView.setLayoutParams(params);
        }



        private void swipeDo(float distance,float velocity) {
            if(distance >=0){
                doneIt(mView,velocity);
            }else{
                shareIt(mView);
                swipe(0);
            }
        }



    }



}
